#include "dirver_dht11.h"
#include "delay.h"

/**  
* @简要  DTAT引脚设置为output
  * @参数  无
  * @注意	无
  * @返回值 无  
  */
void DHT11_GPIO_SetOut(void){
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Pin = DHT11_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;	
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
}

/**  
* @简要  DTAT引脚设置为input
  * @参数  无
  * @注意	无
  * @返回值 无  
  */
void DHT11_GPIO_SetIn(void){
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Pin = DHT11_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;	//上拉
	HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
}

/**  
* @简要  获取一个字节
  * @参数  无
  * @注意	无
  * @返回值 无  
  */
uint8_t  DHT11_Rec_Byte(void){
	uint8_t i, temp = 0;

	for (i = 0; i < 8; i++){
		while (DHT11_ReadPin == 0);		// 等待低电平结束
		
		delay_us(40);			//	延时 40 微秒
		
		if (DHT11_ReadPin == 1){
			while (DHT11_ReadPin == 1);	// 等待高电平结束
			
			temp |= (uint8_t)(0X01 << (7 - i));			// 先发送高位
		}
		else{
			temp &= (uint8_t)~(0X01 << (7 - i));
		}
	}
	return temp;
}

/**  
* @简要  获取数据
  * @参数  DHT11_Data_TypeDef
  * @注意	无
  * @返回值 0或1 
  */
uint8_t DHT11_REC_Data(DHT11_Data_TypeDef *DHT11_Data){
	DHT11_GPIO_SetOut();			// 主机输出，主机拉低
	DHT11_PULL_0;	
	delay_ms(20);				// 延时 18 ms
	
	DHT11_PULL_1;					// 主机拉高，延时 30 us
	delay_us(30);	

	DHT11_GPIO_SetIn();				// 主机输入，获取 DHT11 数据
	
	if (DHT11_ReadPin == 0)	{			// 收到从机应答
		while (DHT11_ReadPin == 0);		// 等待从机应答的低电平结束
		
		while (DHT11_ReadPin == 1);		// 等待从机应答的高电平结束
		
		/*开始接收数据*/   
		DHT11_Data->humi_int  = DHT11_Rec_Byte();
		DHT11_Data->humi_dec = DHT11_Rec_Byte();
		DHT11_Data->temp_int  = DHT11_Rec_Byte();
		DHT11_Data->temp_dec = DHT11_Rec_Byte();
		DHT11_Data->check_sum = DHT11_Rec_Byte();
		
		DHT11_GPIO_SetOut();		// 读取结束，主机拉高
		DHT11_PULL_1;	
		
		// 数据校验
		if (DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_dec + DHT11_Data->temp_int + DHT11_Data->temp_dec)	{
			return 1;
		}		
		else{
			return 0;
		}
	}
	else{		// 未收到从机应答
		return 0;
	}
	
}

